package examples.rulesets;

import framework.interfaces.Cell;
import framework.interfaces.RuleSet;

/**
 * Sets up a simulation of Conway's Game of Life with an extra state for testing.
 *
 */
public class ThreeState implements RuleSet {

	public static final boolean TOROIDAL = false;
	public static final int NUM_ROWS = 50;
	public static final int NUM_COLS = 50;
	public static final int NEIGHBORHOOD_SIZE = 8;
	public static final int NUM_STATES = 3;
	public static final int DEFAULT_STATE = 0;
	private static int[][] startingGrid = null;
	private static final int startingMachineState = 0;
	
	//States
	private static final int DEAD = 0;
	private static final int ALIVE = 1;
	private static final int PINK = 2;
	
	public ThreeState(){
		int[][] startGrid = new int[NUM_ROWS][NUM_COLS];
	
		//Null (DEAD) out all cells in grid
		for(int i = 0; i < NUM_ROWS; i++){
			for(int j = 0; j < NUM_COLS; j++){
				startGrid[i][j] = DEAD;
			}
		}
		
		//Set certain cells to ALIVE to create a Glider Gun
		startGrid[0][24] = ALIVE;
		startGrid[1][24] = ALIVE;
		startGrid[5][24] = ALIVE;
		startGrid[6][24] = ALIVE;
		startGrid[1][22] = ALIVE;
		startGrid[5][22] = ALIVE;
		startGrid[2][21] = ALIVE;
		startGrid[3][21] = ALIVE;
		startGrid[4][21] = ALIVE;
		startGrid[2][20] = ALIVE;
		startGrid[3][20] = ALIVE;
		startGrid[4][20] = ALIVE;
		startGrid[5][17] = ALIVE;
		startGrid[4][16] = ALIVE;
		startGrid[5][16] = ALIVE;
		startGrid[6][16] = ALIVE;
		startGrid[7][15] = ALIVE;
		startGrid[3][15] = ALIVE;
		startGrid[5][14] = ALIVE;
		startGrid[2][13] = ALIVE;
		startGrid[8][13] = ALIVE;
		startGrid[2][12] = ALIVE;
		startGrid[8][12] = ALIVE;
		startGrid[3][11] = ALIVE;
		startGrid[7][11] = ALIVE;
		startGrid[4][10] = ALIVE;
		startGrid[5][10] = ALIVE;
		startGrid[6][10] = ALIVE;
		startGrid[4][0] = ALIVE;
		startGrid[5][0] = ALIVE;
		startGrid[4][1] = ALIVE;
		startGrid[5][1] = ALIVE;
		startGrid[2][34] = ALIVE;
		startGrid[3][34] = ALIVE;
		startGrid[2][35] = ALIVE;
		startGrid[3][35] = ALIVE;
		
		startingGrid = startGrid;
	}
	
	/* Conway's Game of Life
	 * A cell with 2 ALIVE neighbors will maintain its state
	 * A DEAD cell with 3 ALIVE neighbors will become ALIVE
	 * Otherwise a cell will become/remain DEAD
	 */
	@Override
	public int getNextState(Cell active) {
		int liveNeighbors = active.getNeighborCount(ALIVE);
		
		if(active.getState() == ALIVE && 
		   (liveNeighbors == 2 || liveNeighbors == 3)){
			//If cell is alive and has 2 or 3 neighbors, it stays alive
			return ALIVE;
		}
		if(active.getState() == DEAD && liveNeighbors == 3){
			//If cell is dead, and has exactly 3 neighbors, it becomes alive
			return ALIVE;
		}
		if(active.getState() == PINK){
			//The PINK DEATH will always remain DEAD
			return PINK;
		}
		return DEAD;
	}

	@Override
	public boolean getToroidal() {
		return TOROIDAL;
	}

	@Override
	public int getGridRows() {
		return NUM_ROWS;
	}

	@Override
	public int getGridCols() {
		return NUM_COLS;
	}

	@Override
	public int getNeighborhoodSize() {
		return NEIGHBORHOOD_SIZE;
	}

	@Override
	public int getNumStates() {
		return NUM_STATES;
	}

	@Override
	public int getDefaultState() {
		return DEFAULT_STATE;
	}

	@Override
	public int[][] getStartingGrid() {
		return startingGrid;
	}

	@Override
	public int getStartingMachineState() {
		return startingMachineState;
		//Conway doesn't have a machine state
	}

	@Override
	public String[] getStateNames() {
		// TODO Auto-generated method stub
		return null;
	}
}
